package com.xiangxg.jvm.memory;

import java.util.ArrayList;
import java.util.List;

public class MyTest1 {
    /*
            虚拟机栈：Stack Frame 栈帧。每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
            每个方法从调用直至执行完成，就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
            每个线程有一个虚拟机栈，属于线程私有的。当线程创建并运行的时候，与之相对应的虚拟机栈就产生。
            栈帧、局部变量表（存放基本类型和引用类型）

            程序计数器：Program Counter,字节码在执行的时候，执行完一条，执行下一条记录在哪一行
            本地方法栈：主要用于处理native方法，跟虚拟机栈的结构类似。
            堆（Heap）:JVM管理的最大一块内存空间
            方法区（Method Area）:存储元信息。永久代（Permanent Generation）,从JDK1.8开始，已经彻底废弃了永久代，使用元空间
            （meta space）
            运行时常量池：方法区的一部分内容。
            直接内存：Direct Memory,堆外内存。并不是由JVM直接管理的内存，而是由操作系统管辖，JVM可以申请

            关于JAVA对象创建的过程
            new 关键字创建对象的3个步骤
            1.在堆内存中创建出对象的实例。
            2.为对象的实例成员变量赋初值
            3.将对象的引用返回

            空闲列表（前提是堆内存空间中已被使用与未被使用的空间交织在一起的，这时，虚拟机就需要通过一个
            列表来记录哪些空间是可以使用哪些空间是已被使用的，接下来找出可以容纳新创建对象的且未被使用的空间，在此空间存放该对象，同时
            还要修改列表上的记录）
            指针碰撞（前提是堆中的空间通过一个指针进行分割，一侧是已经被占用的空间，另一侧是未被占用的空间）

            对象在内存中的布局
            1.对象头
            2.实例数据（即我们在一个类中所声明的各项信息）
            3.对齐填充

            引用访问对象的方式
            1.句柄
            2.直接指针
         */


        /*
        -Xms5m -Xmx5m
         */
        public static void main(String[] args) throws Exception{
            List<MyTest1> list = new ArrayList<>();
            for(;;){
                Thread.sleep(100);
                list.add(new MyTest1());
                System.gc();


            }





















    }

    /*
            虚拟机栈溢出
         */
    public static class MyTest2 {

        public static void main(String[] args) {
            MyTest2 myTest2 = new MyTest2();
            try {

                myTest2.test();
            } catch (Throwable e) {
                System.out.println("============"+myTest2.length);
                e.printStackTrace();
            } finally {
            }
        }
        private int length;

        public int getLength(){
            return length;
        }

        public void test(){
            this.length++;
            test();
        }
    }
}
